package com.zdp.io.aio;

import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.Date;

/**
 * @Author zhengdp
 * @Description
 */
public class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer> {

    private AsynchronousSocketChannel channel;

    public ReadCompletionHandler(AsynchronousSocketChannel channel) {
        if(this.channel == null) {
            this.channel = channel;
        }
    }

    /**
     *
     * @param result
     *          The result of the I/O operation.
     * @param attachment  客户端连接携带过来的数据
     *          The object attached to the I/O operation when it was initiated.
     */
    @Override
    public void completed(Integer result, ByteBuffer attachment) {
        // 读取数据
        attachment.flip();
        byte[] body = new byte[attachment.remaining()];
        attachment.get(body);
        try {
            String req = new String(body,"UTF-8");
            System.out.println("The time server receive order : " + req);
            String currentTIme = "QUERY TIME ORDER".equalsIgnoreCase(req) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
            // 向客户端连接进行写操作
            doWrite(currentTIme);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    private void doWrite(String currentTime) {
        if(StringUtils.isNotBlank(currentTime)) {
           byte[] bytes = currentTime.getBytes();
           ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
           writeBuffer.put(bytes);
           writeBuffer.flip();
           // 异步write
           channel.write(writeBuffer, writeBuffer,
                   new CompletionHandler<Integer, ByteBuffer>() {
                       @Override
                       public void completed(Integer result, ByteBuffer attachment) {
                           // 如果没有完成，则继续进行发送
                           if(attachment.hasRemaining()) {
                               channel.write(attachment, attachment,this);
                           }
                       }

                       @Override
                       public void failed(Throwable exc, ByteBuffer attachment) {
                           try {
                               channel.close();
                           } catch (IOException e) {
                               e.printStackTrace();
                           }
                       }
                   });
        }
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) {
        try {
            this.channel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
